# -*- coding: utf-8 -*-
"""
错误处理模块
"""
import traceback
from typing import Optional, Callable
from PyQt5.QtWidgets import QMessageBox, QWidget
from utils.logger import logger

class ErrorHandler:
    """错误处理器"""
    
    def __init__(self, parent_widget: Optional[QWidget] = None):
        self.parent_widget = parent_widget
        self.error_callbacks = []
    
    def add_error_callback(self, callback: Callable[[Exception], None]):
        """添加错误回调函数"""
        self.error_callbacks.append(callback)
    
    def handle_error(self, error: Exception, show_message: bool = True, 
                    log_error: bool = True, custom_message: str = ""):
        """处理错误"""
        # 记录错误日志
        if log_error:
            logger.log_exception(f"错误处理: {custom_message or str(error)}")
        
        # 执行错误回调
        for callback in self.error_callbacks:
            try:
                callback(error)
            except Exception as e:
                logger.error(f"错误回调执行失败: {e}")
        
        # 显示错误消息
        if show_message and self.parent_widget:
            self.show_error_message(error, custom_message)
    
    def show_error_message(self, error: Exception, custom_message: str = ""):
        """显示错误消息"""
        if custom_message:
            message = custom_message
        else:
            message = self.get_friendly_error_message(error)
        
        QMessageBox.critical(
            self.parent_widget,
            "错误",
            f"{message}\n\n详细信息: {str(error)}"
        )
    
    def get_friendly_error_message(self, error: Exception) -> str:
        """获取友好的错误消息"""
        error_type = type(error).__name__
        error_msg = str(error)
        
        # 数据库连接错误
        if "pymysql" in error_msg or "MySQL" in error_msg:
            if "Access denied" in error_msg:
                return "数据库访问被拒绝，请检查用户名和密码"
            elif "Can't connect" in error_msg:
                return "无法连接到数据库服务器，请检查主机地址和端口号"
            elif "Unknown database" in error_msg:
                return "数据库不存在，请检查数据库名称"
            else:
                return "数据库连接错误"
        
        # 文件操作错误
        elif "Permission denied" in error_msg:
            return "文件访问权限不足，请检查文件路径和权限"
        elif "No such file or directory" in error_msg:
            return "文件或目录不存在"
        elif "Disk full" in error_msg:
            return "磁盘空间不足"
        
        # 网络错误
        elif "Connection refused" in error_msg:
            return "连接被拒绝，请检查网络连接"
        elif "Timeout" in error_msg:
            return "连接超时，请检查网络连接"
        
        # 内存错误
        elif "MemoryError" in error_type:
            return "内存不足，请关闭其他程序后重试"
        
        # 编码错误
        elif "UnicodeDecodeError" in error_type or "UnicodeEncodeError" in error_type:
            return "字符编码错误，请检查文件编码格式"
        
        # 默认错误消息
        else:
            return f"发生错误: {error_type}"
    
    def handle_database_error(self, error: Exception, operation: str = ""):
        """处理数据库错误"""
        friendly_msg = f"数据库操作失败: {operation}"
        self.handle_error(error, custom_message=friendly_msg)
    
    def handle_file_error(self, error: Exception, operation: str = ""):
        """处理文件错误"""
        friendly_msg = f"文件操作失败: {operation}"
        self.handle_error(error, custom_message=friendly_msg)
    
    def handle_export_error(self, error: Exception, export_format: str = ""):
        """处理导出错误"""
        friendly_msg = f"导出失败: {export_format}格式导出时发生错误"
        self.handle_error(error, custom_message=friendly_msg)
    
    def handle_network_error(self, error: Exception, operation: str = ""):
        """处理网络错误"""
        friendly_msg = f"网络操作失败: {operation}"
        self.handle_error(error, custom_message=friendly_msg)

class ValidationError(Exception):
    """验证错误"""
    pass

class ConnectionError(Exception):
    """连接错误"""
    pass

class ExportError(Exception):
    """导出错误"""
    pass

class FileError(Exception):
    """文件错误"""
    pass

def validate_database_connection_params(host: str, port: int, database: str, 
                                      username: str, password: str) -> None:
    """验证数据库连接参数"""
    if not host or not host.strip():
        raise ValidationError("主机地址不能为空")
    
    if not isinstance(port, int) or port < 1 or port > 65535:
        raise ValidationError("端口号必须是1-65535之间的整数")
    
    if not database or not database.strip():
        raise ValidationError("数据库名称不能为空")
    
    if not username or not username.strip():
        raise ValidationError("用户名不能为空")
    
    if not password:
        raise ValidationError("密码不能为空")

def validate_export_params(file_path: str, file_name: str, export_format: str) -> None:
    """验证导出参数"""
    if not file_path or not file_path.strip():
        raise ValidationError("文件保存路径不能为空")
    
    if not file_name or not file_name.strip():
        raise ValidationError("文件名不能为空")
    
    if not export_format or not export_format.strip():
        raise ValidationError("导出格式不能为空")
    
    # 验证文件名
    invalid_chars = '<>:"/\\|?*'
    if any(char in file_name for char in invalid_chars):
        raise ValidationError(f"文件名包含非法字符: {invalid_chars}")

def safe_execute(func: Callable, *args, **kwargs) -> tuple[bool, any]:
    """安全执行函数"""
    try:
        result = func(*args, **kwargs)
        return True, result
    except Exception as e:
        logger.log_exception(f"安全执行失败: {func.__name__}")
        return False, e
